<?php

namespace services\member;

use api\modules\v1\forms\member\MemberForm;
use common\components\Service;
use common\helpers\CommonHelper;
use common\helpers\DateHelper;
use common\helpers\RedisHelper;
use common\helpers\ValidatorHelper;
use common\models\base\Department;
use common\models\base\Job;
use common\models\member\Attr;
use common\models\member\Member;
use common\models\rbac\Action;
use Exception;
use services\api\AccessTokenService;
use services\base\DepartmentService;
use services\base\JobService;
use services\base\ProjectService;
use services\buss\AccountsService;
use services\buss\DevicesService;
use services\buss\ScardService;
use services\log\LogMemberOpService;
use services\rbac\ActionService;
use services\rbac\MenuService;
use services\rbac\RolePermissionService;
use services\rbac\RoleService;
use services\rbac\UserRoleService;
use Yii;

/**
 * Class MemberService
 * @package services\member
 *
 */
class MemberService extends Service
{
    /**
     * 用户列表
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getListPage(array $params = [], int $page = 0, int $pageSize = 0): array
    {
        $query = Member::find()->alias('m')
            ->select([
                'm.*',
                'ma.project_id', 'ma.department_id', 'ma.job_id',
            ])
            ->innerJoin(Attr::tableName().' ma', 'ma.member_id = m.id')
            ->where(['!=', 'm.super_type', Member::SUPER_TYPE_SUPER_ADMIN]);

        // 权限【项目、部门】
        $memberAuth = MemberService::getLoginMemberLimit();
        // 是超管直接跳过
        if ($memberAuth['super_type'] != Member::SUPER_TYPE_SUPER_ADMIN) {
            // 是否为项目管理员
            if ($memberAuth['admin_project_ids']) {
                $query->andWhere([
                    'or',
                    ['m.id' => array_unique(MemberProjectService::getMemberIdsByProjectId($memberAuth['admin_project_ids']))],// 是【一个或几个】项目管理员则查全项目数据
                    ['m.id' => $memberAuth['all_member_ids']] // 以及权限下的数据【不是项目管理员】
                ]);
            } else {
                $query->andWhere(['m.id' => $memberAuth['all_member_ids']]);
            }
        }

        if (isset($params['keyword']) && $params['keyword']) {
            if (ValidatorHelper::validateMobile($params['keyword'])) {
                $query->andWhere(['m.mobile' => $params['keyword']]);
            } else {
                $query->andWhere(['like', 'm.realname', $params['keyword']]);
            }
        }
        // 项目
        if (!isset($params['project_id']) || empty($params['project_id'])) {
            $params['project_id'] = array_column(MemberService::getProjectListCondition(), 'value');
        }
        $query->andWhere(['m.id' => array_unique(MemberProjectService::getMemberIdsByProjectId($params['project_id']))]);

        if (isset($params['department_id']) && $params['department_id']) {
//            $cityCondition = [];
//            foreach ($params['department_id'] as $id) {
//                $cityCondition[] = "JSON_CONTAINS(ma.department_id, '{$id}')";
//            }
//            $query->andWhere(new Expression(implode(' OR ', $cityCondition)));
            $department = RedisHelper::getDepartment($params['department_id']);
            if ($department->data_level == Department::DATA_LEVEL_DEPARTMENT_ALL) {// 部门本部门+子部门，查询其下所有部门
                $childDepartmentList = DepartmentService::getChildDepartmentList($department->tree_id);
                $childIds = array_column($childDepartmentList, 'id');
                $childIds[] = $params['department_id'];
                $params['department_id'] = $childIds;
            }
            $query->andWhere(['m.id' => array_unique(MemberDepartmentService::getMemberIdsByDepartmentId($params['department_id']))]);
        }

        if (isset($params['role_id']) && $params['role_id']) {
            $query->andWhere(['m.id' => UserRoleService::getRoleUserIds($params['role_id'])]);
        }
        if (isset($params['status']) && is_numeric($params['status'])) {
            $query->andWhere(['m.status' => $params['status']]);
        } else {
            $query->andWhere(['m.status' => [Member::STATUS_INVALID, Member::STATUS_ENABLE]]);
        }
        if (isset($params['order_column']) && $params['order_column']) {
            $sort = isset($params['order_sort']) && $params['order_sort'] == 'asc' ? SORT_ASC : SORT_DESC;
            switch ($params['order_column']) {
                case 'last_time':
                    $order['m.last_time'] = $sort;
                    break;
                default :
                    break;
            }
        }
        $order['status'] = SORT_DESC;
        $order['id'] = SORT_DESC;

        return $this->getListPageRes($query, $page, $pageSize, $order);
    }

    /**
     * 格式化列表
     * @param array $data
     * @return array
     */
    public function getListPageFormat(array $data = []): array
    {
        $list = [];
        foreach ($data as $row) {
            $projectIds = $row['project_id'] ? json_decode($row['project_id'], true) : [];
            $departmentIds = $row['department_id'] ? json_decode($row['department_id'], true) : [];
            $roleData = self::getMemberRoleIds($row['id']);
            $job = RedisHelper::getJob($row['job_id']);
            $list[] = [
                'id' => $row['id'],
                'username' => $row['username'],
//                'realname' => $row['realname'],
                'mobile' => $row['mobile'],
                'project_name_arr' => array_column(ProjectService::getNormalCacheListByIds($projectIds), 'project_name'),
//                'department_name_arr' => array_column(DepartmentService::getNormalCacheListByIds($departmentIds), 'department_name'),
                'department_name_arr' => DepartmentService::getParent($departmentIds[0]),
                'role_name_arr' => array_column(RoleService::getNormalCacheListByIds($roleData['all_role_ids']), 'name'),
                'job_name' => $job && $job->status != Job::STATUS_DELETE ? $job->job_name : '',
//                'status' => $row['status'],
                'status_str' => Member::$statuss[$row['status']] ?? '',
                'last_time_str' => DateHelper::timestampToDate($row['last_time'], DateHelper::DATE_FORMAT_4),
//                'created_at_str' => DateHelper::timestampToDate($row['created_at']),
            ];
        }
        return $list;
    }

    /**
     * 列表筛选项
     * @return array
     */
    public function getSelectCondition(): array
    {
        return [
            'project' => MemberService::getProjectListCondition(),
            'department' => MemberService::getMemberDepartmentCondition()['list'],
            'role' => RoleService::getListCondition(),
            'status' => self::getStatusCondition(),
        ];
    }

    /**
     * 状态下拉筛选项
     * @return array[]
     */
    public static function getStatusCondition(): array
    {
        return [
            ['value' => Member::STATUS_ENABLE, 'label' => Member::$statuss[Member::STATUS_ENABLE]],
            ['value' => Member::STATUS_INVALID, 'label' => Member::$statuss[Member::STATUS_INVALID]],
        ];
    }

    /**
     * 根据Ids获取有效人员列表
     * @param array|int|null $orIds
     * @return Member[]
     */
    public static function getEnableListByIds(?array $ids = null, $orIds = null): array
    {
        $query = Member::find()
            ->where([
                'status' => Member::STATUS_ENABLE
            ])
            ->andWhere(['!=', 'super_type', Member::SUPER_TYPE_SUPER_ADMIN]);
        if (!is_null($ids)) {
            $query->andWhere(['id' => $ids]);
        }
        if ($orIds) {
            $query->orWhere(['id' => $orIds, 'status' => [Member::STATUS_INVALID, Member::STATUS_ENABLE]]);
        }
        return $query->orderBy(['id' => SORT_ASC])->all();
    }

    /**
     * 根据Ids获取人员列表【禁用 + 正常】
     * @param array|null $ids 指定人员IDs
     * @return Member[]
     */
    public static function getNormalListByIds(?array $ids = []): array
    {
        $query = Member::find()
            ->select(['*'])
            ->where([
                'status' => [Member::STATUS_INVALID, Member::STATUS_ENABLE],
            ]);
        if (!is_null($ids)) {
            $query->andWhere(['id' => $ids]);
        }
        return $query->orderBy(['id' => SORT_ASC])->all();
    }

    /**
     * 获取项目下正常的人员数据
     * @param int|null $projectId
     * @param int|null $departmentId
     * @param int|array|null $orIds
     * @return array
     */
    public static function getMemberByProject(int $projectId = null, int $departmentId = null, $orIds = null): array
    {
        if (!$projectId && !$departmentId) {
            return [];
        }
        // 项目下人员
        $memberProjectArr = [];
        // 部门下人员
        $memberDepartmentArr = [];
        $projectId && $memberProjectArr = MemberProjectService::getMemberIdsByProjectId($projectId);

        // 部门存在
        if ($departmentId) {
            $departmentList = DepartmentService::getEnableListByIds([$departmentId]);
            $department = $departmentList[0];// 部门详情
            // 本部门 / 本人
            if ($department->data_level == Department::DATA_LEVEL_SELF || $department->data_level == Department::DATA_LEVEL_DEPARTMENT_NOW) {
                $memberDepartmentArr = MemberDepartmentService::getMemberIdsByDepartmentId($departmentId);
            } else { // 本部门及子部门
                $childDepartmentList = DepartmentService::getChildDepartmentList($department->tree_id);
                $childIds = array_column($childDepartmentList, 'id');
                $allIds = array_merge([$department->id], $childIds);
                $memberDepartmentArr = MemberDepartmentService::getMemberIdsByDepartmentId($allIds);
            }
        }

        // 取交集
        $memberArr = $projectId && $departmentId ? array_unique(array_intersect($memberDepartmentArr, $memberProjectArr)) : ($memberDepartmentArr ?: $memberProjectArr);
        $query = Member::find()
            ->where([
                'id' => $memberArr,
            ])
            ->andWhere(['status' => Member::STATUS_ENABLE])
            ->andWhere(['!=', 'super_type', Member::SUPER_TYPE_SUPER_ADMIN]);
        if ($orIds) {
            $query->orWhere(['id' => $orIds, 'status' => [Member::STATUS_INVALID, Member::STATUS_ENABLE]]);
        }
        $list = $query->orderBy(['id' => SORT_ASC])->all();
        return CommonHelper::getListCondition($list, ['value_column' => 'id', 'label_column' => 'realname']);
    }

    /**
     * 获取列表筛选项
     * @param array $ids
     * @return array
     */
    public static function getListCondition(array $ids = []): array
    {
        return CommonHelper::getListCondition(self::getNormalListByIds($ids), ['value_column' => 'id', 'label_column' => 'realname']);
    }

    /**
     * 获取编辑筛选项
     * @param array|int|null $ids
     * @param array|int|null $orIds
     * @return array
     */
    public static function getEditCondition($ids, $orIds = null): array
    {
        return CommonHelper::getListCondition(self::getEnableListByIds($ids, $orIds), ['value_column' => 'id', 'label_column' => 'realname']);
    }

    /**
     * 用户信息
     * @param int $id
     * @return array
     */
    public function getInfo(int $id): array
    {
        $data = [];
        $member = Member::findOne($id);
        if ($member) {
            $attr = Attr::findOne(['member_id' => $id]);
            $job = RedisHelper::getJob($attr->job_id);
            // 用户角色
            $roleData = self::getMemberRoleIds($member->id);
            $data = [
                'id' => $member->id,
                'username' => $member->username,
                'mobile' => $member->mobile,
                'status' => $member->status,
                'project_id' => $attr->project_id,
                'department_id' => $attr->department_id,
                'job_id' => $job->id ?? 0,
                'role_id' => $roleData['all_role_ids'],
//                    'super_type' => $member->super_type,
            ];
        }

        // 部门筛选【一个人员只能设置一个部门】
        $departmentCondition = MemberService::getMemberDepartmentCondition($data['department_id'][0] ?? null);
        $departmentList = DepartmentService::getEnableListByIds($data['department_id'] ?? []);
        $roleIds = [];
        foreach ($departmentList as $department) {
            $roleIds = array_merge($roleIds, $department->select_role_ids);
        }

        $condition = [
            'project' => ProjectService::getEditCondition($data['project_id'] ?? null),
            'department' => $departmentCondition['list'],// 一个人就一个部门
            'department_disabled' => $departmentCondition['disabled'],// 一个人就一个部门
            'job' => JobService::getEditCondition($data['job_id'] ?? null),
            'role' => RoleService::getEditCondition($roleIds,$data['role_id'] ?? null),
        ];
        // 部门默认角色不可编辑
        foreach ($condition['role'] as $key => $row) {
            $row['disabled'] = isset($roleData['dep_role_ids']) && in_array($row['value'], $roleData['dep_role_ids']) ? 1 : 0;
            $condition['role'][$key] = $row;
        }
        if ($data) {
            $data['project_id'] = array_intersect($data['project_id'], array_column($condition['project'], 'value'));
            $data['department_id'] = array_intersect($data['department_id'], self::getTreeDepartmentIds($departmentCondition['list']));
            if (in_array($data['job_id'], array_column($condition['job'], 'value')) === false) {
                $data['job_id'] = 0;
            }
            $data['role_id'] = array_intersect($data['role_id'], array_column($condition['role'], 'value'));
        }
        return array_merge($data, ['condition' => $condition]);
    }

    /**
     * 编辑修改部门，返回计算结果
     * @param $depIds
     * @param array $roleIds
     * @return array
     */
    public static function getChangeMemberDepartmentIds($depIds, array $roleIds): array
    {
        $defaultRoleIds = [];
        $selectRoleIds = [];
        $departmentList = DepartmentService::getEnableListByIds($depIds);
        foreach ($departmentList as $department) {
            $selectRoleIds = array_merge($selectRoleIds, $department->select_role_ids);
            $department->default_role_id && $defaultRoleIds[] = $department->default_role_id;
        }
        // 计算选中参数
        $paramsRoleIds = array_merge(array_values(array_intersect($roleIds, $selectRoleIds)), $defaultRoleIds);

        $roleList = RoleService::getEditCondition($selectRoleIds, $selectRoleIds);
        foreach ($roleList as $key => $row) {
            $row['disabled'] = in_array($row['value'], $defaultRoleIds) ? 1 : 0;
            $roleList[$key] = $row;
        }
        return [
            'role_id' => $paramsRoleIds,
            'condition' => [
                'role' => $roleList
            ],
        ];
    }

    /**
     * 获取登陆用户权限
     * @return array
     */
    public function getMemberPerssions()
    {
        $member = Member::findOne(Yii::$app->user->identity->member_id);

        // 1.获取用户列表权限
        $rolePermissionService = new RolePermissionService();
        $auth = $rolePermissionService->getMemberPermissions($member);

        return [
            'auth' => $auth,// 权限
        ];
    }

    /**
     * 验证权限
     * @param Member $member 用户信息
     * @param string $route 路由
     * @return bool
     */
    public static function checkPermission(Member $member, string $route): bool
    {
        // 超管无需验证
        if ($member->super_type == Member::SUPER_TYPE_SUPER_ADMIN) {
            return true;
        }

        // 权限信息
        $action = Action::findOne([
            'flag' => $route,
            'status' => Action::STATUS_ENABLE,
        ]);
        if ($action) {
            // 项目负责人【跳过】
//            $attr = Yii::$app->services->attr->findInfo([
//                'member_id' => $member['id'],
//                'project_id' => $projectId,
//            ]);
//            if ($attr && $attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_PROJECT) {
//                return true;
//            }

            // 用户角色
            $roleData = self::getMemberRoleIds($member->id);
            $actionList = RolePermissionService::getActionList($roleData['all_role_ids']);

            $actionIds = array_column($actionList, 'id');
            return in_array($action->id, $actionIds);
        }

        return true;
    }

    /**
     * 获取当前用户绑定项目IDs
     * @return array|null 超管返回null,其他返回绑定项目IDs
     */
    public static function getMemberProjectIds(): ?array
    {
        if (Yii::$app->user->identity->member->super_type == Member::SUPER_TYPE_NORMAL) {
            $attr = Attr::findOne(['member_id' => Yii::$app->user->identity->member_id]);
            /**
             * @var int[] $ids
             */
            $ids = $attr->project_id;
        } else {
            $ids = null;
        }
        return $ids;
    }

    /**
     * 获取用户所有角色
     * @param int $id
     * @return array
     */
    public static function getMemberRoleIds(int $id): array
    {
        // 获取用户绑定部门默认角色
        $depRoleIds = MemberDepartmentService::getUserRoleEnableIds($id);
        // 获取用户绑定角色
        $roleIds = UserRoleService::getUserRoleEnableIds($id);
        $roleIds = array_values(array_diff($roleIds, $depRoleIds));

        return [
            'all_role_ids' => array_merge($roleIds, $depRoleIds),
            'role_ids' => $roleIds,
            'dep_role_ids' => $depRoleIds,
        ];
    }

    /**
     * 获取登陆用户列表下拉筛选
     * @return array
     */
    public static function getProjectListCondition(): array
    {
        return CommonHelper::getListCondition(ProjectService::getNormalListByIds(self::getMemberProjectIds()), [
            'value_column' => 'id',
            'label_column' => 'project_name'
        ]);
    }

    /**
     * 获取所有项目下拉【包括删除的项目--在列表数据用到】
     * @return array
     */
    public static function getAllProjectListCondition(): array
    {
        return CommonHelper::getListCondition(ProjectService::getAllListByIds(self::getMemberProjectIds()), [
            'value_column' => 'id',
            'label_column' => 'project_name'
        ]);
    }

    /**
     * 当前登录人权限
     * @return array
     */
    public static function getLoginMemberLimit(): array
    {
        return self::getMemberLimit(Yii::$app->user->identity->member);
    }

    /**
     * 获取用户权限
     * @param Member $member
     * @return array
     */
    public static function getMemberLimit(Member $member): array
    {
        $memberId = $member->id;
        if ($member->super_type != Member::SUPER_TYPE_SUPER_ADMIN) {
            $departmentArr = self::getMemberDepartmentLimit($memberId);
            $adminProjectIds = MemberProjectService::getAdminProjectIdsByMemberId($memberId);
            $memberProjectIds = MemberProjectService::getProjectIdsByMemberId($memberId);
        }

        return [
            'super_type' => $member->super_type,
            'bind_department_ids' => $departmentArr['bind_department_ids'] ?? null,// 绑定部门
            'all_member_ids' => $departmentArr['all_member_ids'] ?? null,// 权限下所有部门人员ID
            'all_department_ids' => $departmentArr['all_department_ids'] ?? null,// 权限下所有部门
            'admin_project_ids' => $adminProjectIds ?? null,// 项目管理员所在项目IDs
            'member_project_ids' => $memberProjectIds ?? null,// 人员所在项目IDs
        ];
    }

    /**
     * 人员部门数据权限
     * @param $memberId
     * @return array
     */
    public static function getMemberDepartmentLimit($memberId): array
    {
        $bindDepartmentIds = $allDepartmentIds = $allMemberIds = [];
        // 部门
        $departmentList = DepartmentService::getEnableListByIds(MemberDepartmentService::getDepartmentIdsByMemberId($memberId));
        foreach ($departmentList as $department) {
            // 是否为部门负责人
            $isDepartmentLeader = in_array($memberId, $department->leader_member_ids);
            if ($department->data_level == Department::DATA_LEVEL_SELF && $isDepartmentLeader === false) {// 本人 && 非部门管理员
                $allMemberIds[] = $memberId;
                $allDepartmentIds[] = $department->id;
            } else {
                if ($department->data_level == Department::DATA_LEVEL_DEPARTMENT_NOW || $isDepartmentLeader) {// 本部门 or 部门负责人
                    $allIds = [$department->id];
                } else {// 本部门及子部门
                    // 子部门
                    $childDepartmentList = DepartmentService::getChildDepartmentList($department->tree_id);
                    $childIds = array_column($childDepartmentList, 'id');
                    $allIds = array_merge([$department->id], $childIds);
                }
                $allMemberIds = array_merge($allMemberIds, MemberDepartmentService::getMemberIdsByDepartmentId($allIds));
                if (in_array(0, $allMemberIds) === false) {// 本部门及其子部门可以查看未绑定人员的数据
                    $allMemberIds[] = 0;
                }
                $allDepartmentIds = array_merge($allDepartmentIds, $allIds);
            }
            $bindDepartmentIds[] = $department->id;
        }

        return [
            'data_level' => $department->data_level,
            'bind_department_ids' => $bindDepartmentIds,// 绑定部门
            'all_member_ids' => $allMemberIds,// 权限下所有部门人员ID
            'all_department_ids' => $allDepartmentIds,// 权限下所有部门
        ];

    }

    /**
     * 部门下拉筛选
     * @param int|null $orIds
     * @return array
     */
    public static function getMemberDepartmentCondition(?int $orIds = null): array
    {
        $member = Yii::$app->user->identity->member;
        $memberId = $member->id;
        if ($member->super_type == Member::SUPER_TYPE_SUPER_ADMIN) {
            $departmentService = new DepartmentService();
            $list['list'] = $departmentService->getTreeListFormat($departmentService->getTreeList());
            $list['disabled'] = false;
            return $list;
        }
        $departmentList = DepartmentService::getEnableListByIds(MemberDepartmentService::getDepartmentIdsByMemberId($memberId));
        $department = $departmentList[0];

        $disabled = false;// 部门是否可以编辑
        $list = [];// 部门筛选项
        if ($department->data_level == Department::DATA_LEVEL_SELF || $department->data_level == Department::DATA_LEVEL_DEPARTMENT_NOW) {
            // 人员编辑部门时【部门权限不包含被编辑的人员的部门，则不可修改，直接返回被编辑的人员数据】
            if (!is_null($orIds) && $orIds != $department->id) {
                $department = RedisHelper::getDepartment($orIds);
                $departmentName = $department && $department->status != Department::STATUS_DELETE ? $department->department_name : '';
                $list[] = [
                    'id' => $orIds,
                    'department_name' => $departmentName,
                ];
                $disabled = true;
            } else {
                $list[] = [
                    'id' => $department->id,
                    'department_name' => $department->department_name,
                ];
            }
        } else {// 本部门及子部门
            $childDepartmentList = DepartmentService::getChildDepartmentList($department->tree_id);
            $allIds = array_merge([$department->id], array_column($childDepartmentList, 'id'));
            // 人员编辑部门时【部门权限不包含被编辑的人员的部门，则不可修改，直接返回被编辑的人员数据】
            if (!is_null($orIds) && !in_array($orIds, $allIds)) {
                $department = RedisHelper::getDepartment($orIds);
                $departmentName = $department && $department->status != Department::STATUS_DELETE ? $department->department_name : '';
                $list[] = [
                    'id' => $orIds,
                    'department_name' => $departmentName,
                ];
                $disabled = true;
            } else {
                $departmentService = new DepartmentService();
                $children = $departmentService->getTreeListFormat($childDepartmentList, $department->id);
                $list[] = [
                    'id' => $department->id,
//                    'level' => $department->level,
                    'department_name' => $department->department_name,
                    'children' => $children,
                ];
            }
        }
        return [
            'list' => $list,
            'disabled' => $disabled,
        ];
    }

    /**
     * 获取树状结构所有部门IDs
     * @param array $list
     * @return array
     */
    public static function getTreeDepartmentIds(array $list): array
    {
        $ids = [];
        foreach ($list as $row) {
            $ids[] = $row['id'];
            $childIds = self::getTreeDepartmentIds($row['children'] ?? []);
            $ids = array_merge($ids, $childIds);
        }
        return $ids;
    }

    /**
     * 获取登陆用户编辑项目筛选
     * @param int|array|null $orIds
     * @return array
     */
    public static function getProjectEditCondition($orIds = null): array
    {
        return CommonHelper::getListCondition(ProjectService::getEnableListByIds(self::getMemberProjectIds(), $orIds), [
            'value_column' => 'id',
            'label_column' => 'project_name'
        ]);
    }

    /**
     * 获取当前用户权限【菜单 + 动作】
     * @param Member $member
     * @param int $roleId
     * @return array
     */
    public static function getMemberLimitData(Member $member, int $roleId = 0): array
    {
        $hasRoleIds = [];
        if ($member->super_type == Member::SUPER_TYPE_SUPER_ADMIN) {// 超管or项目管理员
            $menuList = MenuService::getEnableList();
            $actionList = ActionService::getEnableList();
        } else {
            // 获取用户绑定角色
            $roleData = self::getMemberRoleIds($member->id);
            $hasRoleIds = $roleData['role_ids'];
            $roleIds = $roleData['all_role_ids'];
            $roleId && $roleIds[] = $roleId;
            $menuList = RolePermissionService::getMenuList($roleIds);
            $actionList = RolePermissionService::getActionList($roleIds);
        }
        return [
            'role_ids' => $hasRoleIds,// 用户绑定角色IDs
            'menu' => $menuList,
            'action' => $actionList,
        ];
    }

    /**
     * 记录最近一次登陆时间、IP
     * @param Member $member
     * @return void
     * @throws Exception
     */
    public static function lastLogin(Member $member): void
    {
        // 1.记录访问次数
        $member->visit_count += 1;
        $member->last_time = time();
        $member->last_ip = Yii::$app->request->getUserIP();
        $member->saveAndCheckResult();
    }

    /**
     * 编辑项目
     * @param Member $member
     * @param MemberForm $model
     * @return Member
     * @throws \Exception
     */
    public static function editModel(Member $member, MemberForm $model): Member
    {
        $member->username = $model->username;
        $member->realname = $model->username;
        $member->mobile = $model->mobile;
        if ($model->password) {
            $member->password_hash = Yii::$app->security->generatePasswordHash($model->password);
            $member->auth_key = Yii::$app->security->generateRandomString();
        }
        $member->super_type = Member::SUPER_TYPE_NORMAL;
        /*if (Yii::$app->user->identity->member->super_type == Member::SUPER_TYPE_SUPER_ADMIN) {
            $member->super_type = $model->super_type;
        }*/
        $member->status = $model->status;
        $member->saveAndCheckResult();

        return $member;
    }

    /**
     * 新增用户
     * @param MemberForm $model
     * @return array
     */
    public function create(MemberForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.新增用户
            $member = new Member();
            $member = self::editModel($member, $model);
            // 2.新增attr
            $attr = AttrService::editModel($member, $model);
            // 3.添加角色绑定关系
            UserRoleService::editModel($member, $model);
            // 4.日志
            LogMemberOpService::createMemberLog($model, $member, null, $attr);

            $transaction->commit();
            return ['id' => $member->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 编辑用户
     * @param MemberForm $model
     * @return array
     */
    public function update(MemberForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.编辑用户
            $oldMember = new Member();
            $oldMember->setAttributes($model->getMember()->getAttributes());
            $member = self::editModel($model->getMember(), $model);
            // 2.编辑attr
            $oldAttr = new Attr();
            $oldAttr->setAttributes($model->getMemberAttr()->getAttributes());
            $attr = AttrService::editModel($member, $model);
            // 2-2.部门删除解绑【清空归属人：手机卡、设备、账号】
            if ($delDepartmentIds = array_diff($oldAttr->department_id, $attr->department_id)) {
                ScardService::clearUseMid($member->id, $delDepartmentIds);
                DevicesService::clearUseMid($member->id, $delDepartmentIds);
                AccountsService::clearUseMid($member->id, $delDepartmentIds);
            }
            // 2-3.存在部门变动或者角色变动，强制退出登陆
            if ($delDepartmentIds || array_diff($model->getOldRoleIds(), array_column($model->getRoleList(), 'id'))) {
                AccessTokenService::clearMemeberToken($member->id);
            }
            // 3.编辑角色绑定关系
            UserRoleService::editModel($member, $model);
            // 4.日志
            LogMemberOpService::createMemberLog($model, $member, $oldMember, $attr, $oldAttr);
            // 5.更新缓存
            RedisHelper::setMember($member);

            $transaction->commit();
            return ['id' => $member->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 删除用户
     * @param MemberForm $model
     * @return array
     */
    public function delete(MemberForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.删除用户
            $member = $model->getMember();
            $member->status = Member::STATUS_DELETE;
            $member->saveAndCheckResult();
            // 1-2.退出登陆
            AccessTokenService::clearMemeberToken($member->id);
            // 2.日志
            LogMemberOpService::createMemberLog($model, $member);
            // 3.更新缓存
            RedisHelper::setMember($member);

            $transaction->commit();
            return ['id' => $member->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 修改密码
     * @param MemberForm $model
     * @return array
     */
    public function updatePassword(MemberForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();
            // 1.修改密码
            $member = $model->getMember();
            $member->password_hash = Yii::$app->security->generatePasswordHash($model->new_password);
            $member->auth_key = Yii::$app->security->generateRandomString();
            $member->saveAndCheckResult();

            // 2.日志
            LogMemberOpService::createMemberLog($model, $member);

            $transaction->commit();
            return ['id' => $member->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }
}
